#include <iostream>
#include <thread>
#include <vector>

// 矩阵转置
typedef struct{
    int start;
    int end;
    int m;
    int n; 
    float *a;
    float *b;
}Pot_t;

void transpose_t(Pot_t *p){
    for(int idx=p->start;idx<p->end;idx++){
        int y=idx/p->n;
        int x=idx%p->n;
        p->b[x*p->m+y]=p->a[idx];
    }
}

void t_(float *a,float *b,int m,int n){
    int size = m*n;
    int thread_num = std::thread::hardware_concurrency();
    std::vector<std::thread> threads(thread_num);
    std::vector<Pot_t> mes(thread_num);
    int blocksdim;
    if (size%thread_num != 0) {
        if (size < thread_num) {
            for (int i = 0; i < size; i++) {
                int end = i + 1;
                int start = i;
                mes[i] = Pot_t{start, end, m, n, a, b};
            }
        }else{
            blocksdim = size/(thread_num -1);
            for (int i = 0; i < thread_num; i++) {
                int end;
                if (i == thread_num - 1) {
                    end = size;
                }
                else{
                    end = blocksdim * (i + 1);
                }
                int start = blocksdim * i;
                
                mes[i] = Pot_t{start, end, m, n, a, b};
            }
        }
    }else{
        blocksdim = size/thread_num;

        for (int i = 0; i < thread_num; i++) {
                int end = blocksdim * (i + 1);
                int start = blocksdim * i;
                mes[i] = Pot_t{start, end, m, n, a, b};
            }
    }
    if (size < thread_num) {
        thread_num = size;
    }
    for (int i = 0; i < thread_num; i++) {
        threads[i] = std::thread(transpose_t, &mes[i]);
    }
    for (int i = 0; i < thread_num; i++) {
        threads[i].join();
    }

}

// test
int main(){
    int m=2,n=3;
    float a[6]={1,2,3,4,5,6};
    float b[6];

    t_(a,b,m,n);
    for(int i=0;i<m;i++){
        for(int j=0;j<n;j++){
            std::cout<<a[i*n+j]<<" ";
        }
        std::cout<<std::endl;
    }
    std::cout<< "transpose:"<<std::endl;

    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            std::cout<<b[i*m+j]<<" ";
        }
        std::cout<<std::endl;
    }
}